package com.siqi.hr.system.custom.entity;

import com.siqi.hr.system.common.chan.BeSql;
import com.siqi.hr.system.common.sql.Parsable;
import com.siqi.hr.system.common.sql.SField;
import com.siqi.hr.system.custom.utils.SqlBuildUtils;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.util.Assert;

import java.io.Serializable;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * 实体注册字段对象
 * @author    xiaogq
 * Created by xiaogoingqin on 2016/7/24.
 */
public class FieldRecord implements Serializable, Parsable<SField>, BeSql {

    public SField parse() {
        Assert.notNull(name, "字段名为不存在");
        return new SField(name, entityRecord.parse());
    }

    public SField toSField(){
        return new SField(name, null);
    }

    /**
     * 字段id
     */
    private int id;

    /**
     * 所属的实体
     */
    private EntityRecord entityRecord;

    /**
     * 字段名称
     */
    private String name;

    /**
     * 字段中文名称
     */
    private String inchinese;

    /**
     *  字段是否在列表显示
     */
    private boolean listShow;

    /**
     *  字段是否在过滤条件显示
     */
    private boolean filterShow;

    /**
     * 不在编辑页布局中显示
     */
    private boolean hiddenEdit;

    /**
     * 不在查看页布局中显示
     */
    private boolean hiddenShow;

    /**
     * 引用字段引用的实体
     */
    private EntityRecord quoteEntity;

    /**
     * 是否批量更新 （0：否，1：是默认为0）
     */
    private boolean batchUpdate;

    /**
     * 系统字段（0：否，1：是默认为0）
     */
    private boolean sysField;

    /**
     * 默认值
     */
    private String defaultValue = null;

    /**
     *  字段是否允许为空（0：是，1：否默认值为0）
     */
    private boolean nulldisable;

    /**
     * 字段存值的长度（默认为20个字符）
     */
    private int length = 20;

    /**
     * 数值型精确度(保留几位小数)
     */
    private int precision;

    /**
     * 是否是计算字段（0：否，1：是默认值为0）
     */
    private boolean calField;

    /**
     * 新建时只读（0：否，1：是默认值为0）
     */
    private boolean readOnly;

    /**
     * 字段是否取值唯一 (表示实体内)（0：否，1：是默认值为0）
     */
    private boolean valueUnique;

    /**
     * 字段是否大小写敏感（0：否，1：是默认值为0）
     */
    private boolean caseSensitive;

    /**
     * 字段显示格式（如：金额 #.###.##）
     */
    private String valueFormat;

    /**
     * 字段编辑显示行数(如文本域类型的字段)
     */
    private int editRowCount;

    /**
     * 枚举值共享属性（引用注册字段id）
     */
    private Integer shareFieldId;

    /**
     * 相关项列表隐藏(0:否，1：是默认值为0)
     */
    private boolean relatedHidden;

    /**
     * 是否属性级控制(也就是字段级权限控制)(0:否，1：是默认值为0)
     */
    private boolean controled;

    /**
     * 枚举控制属性引用注册字段id
     */
    private Integer restricter;

    /**
     * 被级联下拉字段引用注册字段id
     */
    private Integer ifcascade;

    /**
     * 排序
     */
    private int position;

    /**
     * 备注（描述）
     */
    private String comment;

    //=======================以下非数据库中表字段

    /**
     * 字段类型id(数据库中无对应)
     */
    private Integer fieldTypeId;

    /**
     * 如果字段为引用类型的字段，存放创建表字段时长度(xiaogq)
     */
    private String colomuDefines;

    /**
     * 如果是下拉框类型字段设置第一个值为默认值(xiaogq)
     */
    private boolean firstAsDefault;

    /**
     * 日期类型字段默认值(xiaogq)
     */
    private int dateType;

    /**
     * 添加的字定义字段是否排序（true:排序，false:不排序）(xiaogq)
     */
    private boolean canOrder;

    /**
     * 引用字段名后缀 author:xiaogq
     */
    private Integer suffix;

    /**
     *  如果是外键添加修改时外键关系(修改时受外键约束还是级联修改) author:xiaogq
     */
    private boolean upRelation = false;

    /**
     *  如果是外键添加删除时外键关系(删除时受外键约束还是级联删除) author:xiaogq
     */
    private boolean deRelation = false;

    public FieldRecord() {
    }

    public FieldRecord(String name) {
        this.name = name;
    }

    public FieldRecord(String name,String inchinese) {
        this.name = name;
        this.inchinese = inchinese;
    }

    public FieldRecord(int id) {
        this.id = id;
    }

    public FieldRecord(EntityRecord entityRecord, String name, String inchinese,boolean sysField,int length) {
        this.entityRecord = entityRecord;
        this.name = name;
        this.inchinese = inchinese;
        this.sysField = sysField;
        this.length = length;
    }

    public FieldRecord(EntityRecord entityRecord, String name, String inchinese,boolean sysField,boolean hiddenEdit) {
        super();
        this.entityRecord = entityRecord;
        this.name = name;
        this.inchinese = inchinese;
        this.sysField = sysField;
        this.hiddenEdit = hiddenEdit;
    }


    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public EntityRecord getEntityRecord() {
        return entityRecord;
    }

    public void setEntityRecord(EntityRecord entityRecord) {
        this.entityRecord = entityRecord;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getInchinese() {
        return inchinese;
    }

    public void setInchinese(String inchinese) {
        this.inchinese = inchinese;
    }

    public boolean isListShow() {
        return listShow;
    }

    public void setListShow(boolean listShow) {
        this.listShow = listShow;
    }

    public boolean isFilterShow() {
        return filterShow;
    }

    public void setFilterShow(boolean filterShow) {
        this.filterShow = filterShow;
    }

    public boolean isHiddenShow() {
        return hiddenShow;
    }

    public void setHiddenShow(boolean hiddenShow) {
        this.hiddenShow = hiddenShow;
    }

    public boolean isHiddenEdit() {
        return hiddenEdit;
    }

    public void setHiddenEdit(boolean hiddenEdit) {
        this.hiddenEdit = hiddenEdit;
    }

    public EntityRecord getQuoteEntity() {
        return quoteEntity;
    }

    public void setQuoteEntity(EntityRecord quoteEntity) {
        this.quoteEntity = quoteEntity;
    }

    public boolean isBatchUpdate() {
        return batchUpdate;
    }

    public void setBatchUpdate(boolean batchUpdate) {
        this.batchUpdate = batchUpdate;
    }

    public boolean isSysField() {
        return sysField;
    }

    public void setSysField(boolean sysField) {
        this.sysField = sysField;
    }

    public String getDefaultValue() {
        return defaultValue;
    }

    public void setDefaultValue(String defaultValue) {
        this.defaultValue = defaultValue;
    }

    public boolean isNulldisable() {
        return nulldisable;
    }

    public void setNulldisable(boolean nulldisable) {
        this.nulldisable = nulldisable;
    }

    public int getLength() {
        return length;
    }

    public void setLength(int length) {
        this.length = length;
    }

    public int getPrecision() {
        return precision;
    }

    public void setPrecision(int precision) {
        this.precision = precision;
    }

    public boolean isCalField() {
        return calField;
    }

    public void setCalField(boolean calField) {
        this.calField = calField;
    }

    public boolean isReadOnly() {
        return readOnly;
    }

    public void setReadOnly(boolean readOnly) {
        this.readOnly = readOnly;
    }

    public boolean isValueUnique() {
        return valueUnique;
    }

    public void setValueUnique(boolean valueUnique) {
        this.valueUnique = valueUnique;
    }

    public boolean isCaseSensitive() {
        return caseSensitive;
    }

    public void setCaseSensitive(boolean caseSensitive) {
        this.caseSensitive = caseSensitive;
    }

    public String getValueFormat() {
        return valueFormat;
    }

    public void setValueFormat(String valueFormat) {
        this.valueFormat = valueFormat;
    }

    public int getEditRowCount() {
        return editRowCount;
    }

    public void setEditRowCount(int editRowCount) {
        this.editRowCount = editRowCount;
    }

    public Integer getShareFieldId() {
        return shareFieldId;
    }

    public void setShareFieldId(Integer shareFieldId) {
        this.shareFieldId = shareFieldId;
    }

    public boolean isRelatedHidden() {
        return relatedHidden;
    }

    public void setRelatedHidden(boolean relatedHidden) {
        this.relatedHidden = relatedHidden;
    }

    public boolean isControled() {
        return controled;
    }

    public void setControled(boolean controled) {
        this.controled = controled;
    }

    public Integer getRestricter() {
        return restricter;
    }

    public void setRestricter(Integer restricter) {
        this.restricter = restricter;
    }

    public Integer getIfcascade() {
        return ifcascade;
    }

    public void setIfcascade(Integer ifcascade) {
        this.ifcascade = ifcascade;
    }

    public int getPosition() {
        return position;
    }

    public void setPosition(int position) {
        this.position = position;
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj != null && obj instanceof FieldRecord) {
            return this.name.equals(((FieldRecord)obj).getName());
        }
        return super.equals(obj);
    }
    @Override
    public int hashCode() {
        if(name == null)
            return super.hashCode();
        return name.hashCode();
    }

    public String getColomuDefines() {
        return colomuDefines;
    }

    public void setColomuDefines(String colomuDefines) {
        this.colomuDefines = colomuDefines;
    }

    public StringBuilder foreignKeyDefinition(){
        Assert.isTrue(parse().isQuote());
        return new StringBuilder().append(" foreign key (" ).append( getName()) .append( ") REFERENCES ").append( parse().getQuoteTable()).append("(id)");
    }

    @Override
    public StringBuilder toSqlString() {
        if( colomuDefines == null ){
            return SqlBuildUtils.buildupColumuOption(parse(),length, defaultValue,precision);
        }else{
            return new StringBuilder( name ).append(" ").append( colomuDefines );
        }
    }

    public boolean isFirstAsDefault() {
        return firstAsDefault;
    }

    public void setFirstAsDefault(boolean firstAsDefault) {
        this.firstAsDefault = firstAsDefault;
    }

    public int getDateType() {
        return dateType;
    }

    public void setDateType(int dateType) {
        this.dateType = dateType;
    }

    public boolean isCanOrder() {
        return canOrder;
    }

    public void setCanOrder(boolean canOrder) {
        this.canOrder = canOrder;
    }

    public Integer getFieldTypeId() {
        return fieldTypeId;
    }

    public void setFieldTypeId(Integer fieldTypeId) {
        this.fieldTypeId = fieldTypeId;
    }

    public Integer getSuffix() {
        return suffix;
    }

    public void setSuffix(Integer suffix) {
        this.suffix = suffix;
    }

    public boolean isUpRelation() {
        return upRelation;
    }

    public void setUpRelation(boolean upRelation) {
        this.upRelation = upRelation;
    }

    public boolean isDeRelation() {
        return deRelation;
    }

    public void setDeRelation(boolean deRelation) {
        this.deRelation = deRelation;
    }

    /**
     * 查询所有字段信息包括实体的一些信息
     * @author 肖功钦(该方法报表里面用到)
     * @date 07 24, 2016
     */
    public static class getFieldAll extends FieldRecord implements RowMapper<FieldRecord> {
        public FieldRecord mapRow(ResultSet rs, int rowNum) throws SQLException {
            FieldRecord f = new FieldRecord();
            f.setId(rs.getInt("id"));
            f.setName(rs.getString("name"));
            f.setInchinese(rs.getString("inchinese"));
            EntityRecord eRecord = new EntityRecord(rs.getInt("entity_id"));
            eRecord.setSystemEntity(rs.getBoolean("system_entity"));
            eRecord.setDefineType(rs.getBoolean("define_type"));
            f.setEntityRecord(eRecord);
            f.setListShow(rs.getBoolean("list_show"));
            f.setFilterShow(rs.getBoolean("filter_show"));
            f.setHiddenEdit(rs.getBoolean("hidden_edit"));
            f.setHiddenShow(rs.getBoolean("hidden_show"));
            f.setCanOrder(rs.getBoolean("can_order"));
            f.setQuoteEntity(new EntityRecord(rs.getInt("quote_entity_id")));
            f.setDefaultValue(rs.getString("default_value"));
            f.setNulldisable(rs.getBoolean("nulldisable"));
            f.setLength(rs.getInt("length"));
            f.setPrecision(rs.getInt("precisions"));
            f.setCalField(rs.getBoolean("calfield"));
            f.setValueUnique(rs.getBoolean("value_unique"));
            f.setCaseSensitive(rs.getBoolean("case_sensitive"));
            f.setFirstAsDefault(rs.getBoolean("first_as_default"));
            f.setEditRowCount(rs.getInt("edit_row_count"));
            f.setDateType(rs.getInt("date_type"));
            f.setReadOnly(rs.getBoolean("read_only"));
            f.setBatchUpdate(rs.getBoolean("batch_update"));
            f.setShareFieldId(rs.getInt("share_field_id"));
            f.setRelatedHidden(rs.getBoolean("related_hidden"));
            f.setControled(rs.getBoolean("controled"));
            f.setRestricter(rs.getInt("restricter"));
            f.setIfcascade(rs.getInt("ifcascade"));
            f.setSysField(rs.getBoolean("sys_field"));
            f.setComment(rs.getString("comment"));
            return f;
        }
    }

    /**
     * 查询布局的表中用到
     * @author 黄殿玺
     * @date Jul 24, 2014
     */
    public static class PartInfo extends FieldRecord implements RowMapper<FieldRecord>{
        public FieldRecord mapRow(ResultSet rs, int index) throws SQLException {
            FieldRecord f = new FieldRecord();
            f.setId(rs.getInt("id"));
            f.setName(rs.getString("name"));
            f.setInchinese(rs.getString("inchinese"));
            f.setShareFieldId(rs.getInt("share_field_id"));
            f.setRestricter(rs.getInt("restricter"));
            f.setIfcascade(rs.getInt("ifcascade"));
            return f;
        }
    }

    public static class MainFieldRecord extends FieldRecord implements RowMapper<FieldRecord>{
        public FieldRecord mapRow(ResultSet rs, int index) throws SQLException {
            FieldRecord f = new FieldRecord();
            f.setId(rs.getInt("id"));
            f.setName(rs.getString("name"));
            f.setInchinese(rs.getString("inchinese"));
            return f;
        }
    }

    public static class ManyFieldRecord extends FieldRecord implements RowMapper<FieldRecord>{
        private static final long serialVersionUID = 2717977930899986716L;
        public FieldRecord mapRow(ResultSet rs, int index) throws SQLException {
            FieldRecord f = new FieldRecord();
            f.setId(rs.getInt("id"));
            f.setName(rs.getString("name"));
            f.setEntityRecord(new EntityRecord(rs.getInt( "entity_id" )));
            f.setInchinese(rs.getString("inchinese").trim());
            f.setListShow(rs.getBoolean("list_show"));
            f.setQuoteEntity(new EntityRecord(rs.getInt("quote_entity_id")));
            f.setNulldisable(rs.getBoolean("nulldisable"));
            f.setValueUnique(rs.getBoolean("value_unique"));
            return f;
        }
    }

    public static class quoteFieldRecord extends FieldRecord implements RowMapper<FieldRecord>{
        private static final long serialVersionUID = 2717977930899986716L;
        public FieldRecord mapRow(ResultSet rs, int index) throws SQLException {
            FieldRecord f = new FieldRecord();
            f.setId(rs.getInt("id"));
            f.setName(rs.getString("name"));
            f.setEntityRecord(new EntityRecord(rs.getInt( "entity_id" )));
            f.setInchinese(rs.getString("inchinese").trim());
            f.setListShow(rs.getBoolean("list_show"));
            f.setQuoteEntity(new EntityRecord(rs.getInt("quote_entity_id")));
            return f;
        }
    }

}
